using System;
using System.Windows.Forms;
using System.Collections.Generic;
using BrainTechLLC;
using System.Collections;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Text;
using System.Runtime.Serialization.Formatters.Soap;



namespace Mud.EmlenMudMain
{
	public class SerializationHelper
	{
		public static bool IsOverwriting(string szFileName, bool fMakeBackup)
		{
			if (File.Exists(szFileName))
			{
				if (fMakeBackup)
				{
					try
					{
						File.Copy(szFileName, szFileName + ".bak", true);
					}
					catch (Exception ex) { EmlenMud.LogError("Could not make a .bak file: ", ex, LogType.Always); }					
				}
				return true;
			}
			return false;
		}

		public static bool SerializeObjectOut(Object obj, string szFileName, bool fMakeBackup)
		{
			return SerializeObjectOutCompressed(obj, szFileName, true);
		}

		public static Object SerializeObjectIn(string szFName)
		{
			return SerializeObjectInCompressed(szFName);
		}

		public static bool SerializeObjectOutSOAP(Object obj, string szFName, bool fMakeBackup)
		{
            string szFileName = szFName + ".xml";
            bool fOverwrite = SerializationHelper.IsOverwriting(szFileName, true);
            string szOutFile = (fOverwrite == true) ? (szFileName + ".new") : szFileName;
            SoapFormatter sf = new SoapFormatter();
            FileStream fs = null;
            try { fs = new FileStream(szOutFile, FileMode.Create, FileAccess.ReadWrite); }
            catch (Exception ex) { EmlenMud.LogError("Error writing " + szOutFile, ex, LogType.Always); return false; }
            try { sf.Serialize(fs, obj); }
            catch (Exception ex) { EmlenMud.LogError("Error serializing " + obj.GetType().Name.ToString() + " to file " + szOutFile, ex, LogType.Always); fs.Close(); return false; }
            fs.Flush(); fs.Close();
            if (fOverwrite == true)
            {
                try
                {
                    File.Copy(szOutFile, szFileName, true);
                }
                catch (Exception ex)
                {
                    EmlenMud.LogError("Error copying " + szOutFile + " to " + szFileName, ex, LogType.Always);
                }
            }
			return true;
		}
		

		public static Object SerializeObjectInCompressed(string szFName)
		{
            string szFileName = szFName + ".ace";
            if (File.Exists(szFileName) == false) return null;
            BinaryFormatter sf = new BinaryFormatter();
            FileStream fs = null;
            Object oIn = null;
            try { fs = new FileStream(szFileName, FileMode.Open, FileAccess.Read); }
            catch (Exception ex) { EmlenMud.LogError("Error reading " + szFileName, ex, LogType.Always); return null; }
            int nRemaining = (int)fs.Length;
            int nPos = 0;
            byte[] rgBuf = new byte[nRemaining];
            while (nRemaining > 0)
            {
                int nRead = fs.Read(rgBuf, nPos, (int)nRemaining);
                nPos += nRead;
                nRemaining -= nRead;
            }
            fs.Close();
            byte[] byt = rgBuf.Decompress();
            MemoryStream ms = new MemoryStream(byt);
            try { oIn = sf.Deserialize(ms); }
            catch (Exception ex) { EmlenMud.LogError("Error serializing " + szFileName + " in : ", ex, LogType.Always); ms.Close(); fs.Close(); return null; }
            ms.Close(); 

            return oIn;
		}
	
		public static bool SerializeObjectOutCompressed(Object obj, string szFName, bool fMakeBackup)
		{
            string szFileName = szFName + ".ace";
            bool fOverwrite = SerializationHelper.IsOverwriting(szFileName, true);
            string szOutFile = (fOverwrite == true) ? (szFileName + ".new") : szFileName;
            BinaryFormatter sf = new BinaryFormatter();
            FileStream fs = null;
            MemoryStream ms = new MemoryStream(256000);
            try { sf.Serialize(ms, obj); }
            catch (Exception ex) { EmlenMud.LogError("Error serializing " + obj.GetType().Name.ToString(), ex, LogType.Always); return false; }            
            byte[] rgDest = ms.Compress();            
            try { fs = new FileStream(szOutFile, FileMode.Create, FileAccess.ReadWrite); }
            catch (Exception ex) { EmlenMud.LogError("Error writing " + szOutFile, ex, LogType.Always); return false; }
            fs.Write(rgDest, 0, rgDest.Length);
            fs.Flush(); fs.Close();
            ms.Close();
            if (fOverwrite == true)
            {
                try
                {
                    File.Copy(szOutFile, szFileName, true);
                }
                catch (Exception ex)
                {
                    EmlenMud.LogError("Error copying " + szOutFile + " to " + szFileName, ex, LogType.WorldError);
                }
            }
			return true;
		}

		public static Object SerializeObjectInSOAP(string szFName)
		{			
            //string szFileName = szFName + ".xml";
            //if (File.Exists(szFileName) == false) return null;
            //SoapFormatter sf = new SoapFormatter();			
            //FileStream fs = null;
            //Object oIn = null;
            //try { fs = new FileStream(szFileName, FileMode.Open, FileAccess.Read); }
            //catch (Exception ex) { EmlenMud.LogError("Error reading " + szFileName, ex, LogType.Always); return null; }
            //try { oIn = sf.Deserialize(fs); }
            //catch (Exception ex) { EmlenMud.LogError("Error serializing " + szFileName + " in", ex, LogType.Always); fs.Close(); return null; }
            //fs.Close();
            //return oIn;
            return null;
		}
	}

}
